"use strict";
// 装饰器
// 一、类装饰器
// 1、基本语法：类庄思琪是一个应用在类声明上的函数，可以为类添加额外的功能，或添加额外的逻辑
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
// 装饰器函数
function DemoPerson(target) {
    console.log('我是装饰器函数', target);
}
// 使用装饰器
let PersonDecoration = class PersonDecoration {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
};
PersonDecoration = __decorate([
    DemoPerson //这句代码其实就是等价于： DemoPerson(PersonDecoration)
], PersonDecoration);
// DemoPerson 函数会在PersonDecoration类定义时执行
// 参数说明：target 参数是被装饰的类，即：PersonDecoration
// 重点注释：使用装饰器必须在class类的上面一行
// 2、案例：调用demotest1的toString方法打印的是JSON字符串
let Demo1 = class Demo1 {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
};
Demo1 = __decorate([
    CustomString
], Demo1);
const demotest1 = new Demo1('张三', 18);
// console.log('这是原本的toString',demotest1.toString());    //不使用装饰器打印的结果却是："[Object,Object]"
console.log('这是有装饰器的toString', demotest1.toString()); //使用装饰器打印的结果是："{"name":"张三","age":18}"
function CustomString(target) {
    target.prototype.toString = function () {
        return JSON.stringify(this); //这里JSON.stringify()里的参数得是this，而不是target，因为target是类，不是实例变量
    };
    Object.seal(target); //Object.seal()封锁，对prototype进行封锁，不允许随意对prototype进行扩展
}
// 3、关于返回值：
//   类装饰器有返回值：若类装饰器返回一个新的类，那这个新类将替换掉被装饰的类
//   类装饰器无返回值: 若类装饰器无返回值或返回undefined，那么装饰器的类不会被替换
function xiha(target) {
    return class {
        test() {
            console.log(100);
            console.log(200);
            console.log(300);
        }
    };
}
let xihatest = class xihatest {
    test() {
        console.log(111);
    }
};
xihatest = __decorate([
    xiha
], xihatest);
console.log('xihatest', xihatest);
// new：表示该类型可以被new操作符调用    ...agrs：构造器可以接受多个参数
// any[]：表示构造器可以接受任意类型的参数  {}:表示返回类型是对象(非null、非undefined的对象)
// 需求fn得是一个类
function testFn(fn) { }
const personAxios = () => { };
// testFn(personAxios)   //报错
class personClass {
}
testFn(personClass);
// (2)、申明构造类型 + 指定静态属性
function WifeTest(fn) { }
class wifePerson {
}
WifeTest(wifePerson);
function LogTime(target) {
    //T extends tmieType 这里的extends不是继承，而是对泛型T的一个变量限制，使T只能是符合timeType定义的对象类型 
    return class extends target {
        constructor(...args) {
            super(...args);
            this.createTime = new Date();
        }
        getTime() {
            console.log('该对象的创建时间是:' + this.createTime);
        }
    };
}
let ximyPerson = class ximyPerson {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    speak() {
        console.log('你好啊');
    }
};
ximyPerson = __decorate([
    LogTime
], ximyPerson);
const xmyp1 = new ximyPerson('张三', 18);
xmyp1.getTime();
